
const _interopRequireDefault = require('@babel/runtime/helpers/interopRequireDefault');

exports.__esModule = true;
exports.default = void 0;

const _extends5 = _interopRequireDefault(require('@babel/runtime/helpers/extends'));

const _vue = _interopRequireDefault(require('vue'));

const _popup = _interopRequireDefault(require('../popup'));

const _toast = _interopRequireDefault(require('../toast'));

const _imagePreview = _interopRequireDefault(require('../image-preview'));

const _SkuHeader = _interopRequireDefault(require('./components/SkuHeader'));

const _SkuHeaderItem = _interopRequireDefault(require('./components/SkuHeaderItem'));

const _SkuRow = _interopRequireDefault(require('./components/SkuRow'));

const _SkuRowItem = _interopRequireDefault(require('./components/SkuRowItem'));

const _SkuRowPropItem = _interopRequireDefault(require('./components/SkuRowPropItem'));

const _SkuStepper = _interopRequireDefault(require('./components/SkuStepper'));

const _SkuMessages = _interopRequireDefault(require('./components/SkuMessages'));

const _SkuActions = _interopRequireDefault(require('./components/SkuActions'));

const _utils = require('../utils');

const _skuHelper = require('./utils/sku-helper');

const _constants = require('./constants');

const namespace = (0, _utils.createNamespace)('sku');
const createComponent = namespace[0];
const bem = namespace[1];
const t = namespace[2];
const { QUOTA_LIMIT } = _constants.LIMIT_TYPE;

const _default2 = createComponent({
  props: {
    sku: Object,
    priceTag: String,
    goods: Object,
    value: Boolean,
    buyText: String,
    goodsId: [Number, String],
    hideStock: Boolean,
    addCartText: String,
    stepperTitle: String,
    getContainer: [String, Function],
    hideQuotaText: Boolean,
    hideSelectedText: Boolean,
    resetStepperOnHide: Boolean,
    customSkuValidator: Function,
    closeOnClickOverlay: Boolean,
    disableStepperInput: Boolean,
    resetSelectedSkuOnHide: Boolean,
    properties: Array,
    quota: {
      type: Number,
      default: 0,
    },
    quotaUsed: {
      type: Number,
      default: 0,
    },
    startSaleNum: {
      type: Number,
      default: 1,
    },
    initialSku: {
      type: Object,
      default: function _default() {
        return {};
      },
    },
    stockThreshold: {
      type: Number,
      default: 50,
    },
    showSoldoutSku: {
      type: Boolean,
      default: true,
    },
    showAddCartBtn: {
      type: Boolean,
      default: true,
    },
    bodyOffsetTop: {
      type: Number,
      default: 200,
    },
    messageConfig: {
      type: Object,
      default: function _default() {
        return {
          initialMessages: {},
          placeholderMap: {},
          uploadImg: function uploadImg() {
            return Promise.resolve();
          },
          uploadMaxSize: 5,
        };
      },
    },
    customStepperConfig: {
      type: Object,
      default: function _default() {
        return {};
      },
    },
    previewOnClickImage: {
      type: Boolean,
      default: true,
    },
    safeAreaInsetBottom: {
      type: Boolean,
      default: true,
    },
  },
  data: function data() {
    return {
      selectedSku: {},
      selectedProp: {},
      selectedNum: 1,
      show: this.value,
    };
  },
  watch: {
    show: function show(val) {
      this.$emit('input', val);

      if (!val) {
        this.$emit('sku-close', {
          selectedSkuValues: this.selectedSkuValues,
          selectedNum: this.selectedNum,
          selectedSkuComb: this.selectedSkuComb,
        });

        if (this.resetStepperOnHide) {
          this.resetStepper();
        }

        if (this.resetSelectedSkuOnHide) {
          this.resetSelectedSku();
        }
      }
    },
    value: function value(val) {
      this.show = val;
    },
    skuTree: 'resetSelectedSku',
    initialSku: function initialSku() {
      this.resetStepper();
      this.resetSelectedSku();
    },
  },
  computed: {
    skuGroupClass: function skuGroupClass() {
      return ['van-sku-group-container', {
        'van-sku-group-container--hide-soldout': !this.showSoldoutSku,
      }];
    },
    bodyStyle: function bodyStyle() {
      if (this.$isServer) {
        return;
      } // header高度82px, sku actions高度50px，如果改动了样式自己传下bodyOffsetTop调整下


      const maxHeight = window.innerHeight - this.bodyOffsetTop;
      return {
        maxHeight: `${maxHeight}px`,
      };
    },
    isSkuCombSelected: function isSkuCombSelected() {
      const _this = this;

      // SKU 未选完
      if (this.hasSku && !(0, _skuHelper.isAllSelected)(this.skuTree, this.selectedSku)) {
        return false;
      } // 属性未全选


      if (this.propList.some((it) => (_this.selectedProp[it.k_id] || []).length < 1)) {
        return false;
      }

      return true;
    },
    isSkuEmpty: function isSkuEmpty() {
      return Object.keys(this.sku).length === 0;
    },
    hasSku: function hasSku() {
      return !this.sku.none_sku;
    },
    hasSkuOrAttr: function hasSkuOrAttr() {
      return this.hasSku || this.propList.length > 0;
    },
    selectedSkuComb: function selectedSkuComb() {
      let skuComb = null;

      if (this.isSkuCombSelected) {
        if (this.hasSku) {
          skuComb = (0, _skuHelper.getSkuComb)(this.sku.list, this.selectedSku);
        } else {
          skuComb = {
            id: this.sku.collection_id,
            price: Math.round(this.sku.price * 100),
            stock_num: this.sku.stock_num,
          };
        }

        if (skuComb) {
          skuComb.properties = (0, _skuHelper.getSelectedProperties)(this.propList, this.selectedProp);
          skuComb.property_price = this.selectedPropValues.reduce((acc, cur) => acc + (cur.price || 0), 0);
        }
      }

      return skuComb;
    },
    selectedSkuValues: function selectedSkuValues() {
      return (0, _skuHelper.getSelectedSkuValues)(this.skuTree, this.selectedSku);
    },
    selectedPropValues: function selectedPropValues() {
      return (0, _skuHelper.getSelectedPropValues)(this.propList, this.selectedProp);
    },
    price: function price() {
      if (this.selectedSkuComb) {
        return ((this.selectedSkuComb.price + this.selectedSkuComb.property_price) / 100).toFixed(2);
      } // sku.price是一个格式化好的价格区间


      return this.sku.price;
    },
    originPrice: function originPrice() {
      if (this.selectedSkuComb && this.selectedSkuComb.origin_price) {
        return ((this.selectedSkuComb.origin_price + this.selectedSkuComb.property_price) / 100).toFixed(2);
      }

      return this.sku.origin_price;
    },
    skuTree: function skuTree() {
      return this.sku.tree || [];
    },
    propList: function propList() {
      return this.properties || [];
    },
    imageList: function imageList() {
      const imageList = [this.goods.picture];

      if (this.skuTree.length > 0) {
        this.skuTree.forEach((treeItem) => {
          if (!treeItem.v) {
            return;
          }

          treeItem.v.forEach((vItem) => {
            const img = vItem.previewImgUrl || vItem.imgUrl || vItem.img_url;

            if (img) {
              imageList.push(img);
            }
          });
        });
      }

      return imageList;
    },
    stock: function stock() {
      const { stockNum } = this.customStepperConfig;

      if (stockNum !== undefined) {
        return stockNum;
      }

      if (this.selectedSkuComb) {
        return this.selectedSkuComb.stock_num;
      }

      return this.sku.stock_num;
    },
    stockText: function stockText() {
      const h = this.$createElement;
      const { stockFormatter } = this.customStepperConfig;
      if (stockFormatter) return stockFormatter(this.stock);
      return [`${t('stock')} `, h('span', {
        class: bem('stock-num', {
          highlight: this.stock < this.stockThreshold,
        }),
      }, [this.stock]), ` ${t('stockUnit')}`];
    },
    selectedText: function selectedText() {
      const _this2 = this;

      if (this.selectedSkuComb) {
        const values = this.selectedSkuValues.concat(this.selectedPropValues);
        return `${t('selected')} ${values.map((item) => item.name).join('；')}`;
      }

      const unselectedSku = this.skuTree.filter((item) => _this2.selectedSku[item.k_s] === _constants.UNSELECTED_SKU_VALUE_ID).map((item) => item.k);
      const unselectedProp = this.propList.filter((item) => (_this2.selectedProp[item.k_id] || []).length < 1).map((item) => item.k);
      return `${t('select')} ${unselectedSku.concat(unselectedProp).join('；')}`;
    },
  },
  created: function created() {
    const skuEventBus = new _vue.default();
    this.skuEventBus = skuEventBus;
    skuEventBus.$on('sku:select', this.onSelect);
    skuEventBus.$on('sku:propSelect', this.onPropSelect);
    skuEventBus.$on('sku:numChange', this.onNumChange);
    skuEventBus.$on('sku:previewImage', this.onPreviewImage);
    skuEventBus.$on('sku:overLimit', this.onOverLimit);
    skuEventBus.$on('sku:stepperState', this.onStepperState);
    skuEventBus.$on('sku:addCart', this.onAddCart);
    skuEventBus.$on('sku:buy', this.onBuy);
    this.resetStepper();
    this.resetSelectedSku(); // 组件初始化后的钩子，抛出skuEventBus

    this.$emit('after-sku-create', skuEventBus);
  },
  methods: {
    resetStepper: function resetStepper() {
      const { skuStepper } = this.$refs;
      const { selectedNum } = this.initialSku;
      const num = (0, _utils.isDef)(selectedNum) ? selectedNum : this.startSaleNum; // 用来缓存不合法的情况

      this.stepperError = null;

      if (skuStepper) {
        skuStepper.setCurrentNum(num);
      } else {
        // 当首次加载（skuStepper 为空）时，传入数量如果不合法，可能会存在问题
        this.selectedNum = num;
      }
    },
    // @exposed-api
    resetSelectedSku: function resetSelectedSku() {
      const _this3 = this;

      this.selectedSku = {}; // 重置 selectedSku

      this.skuTree.forEach((item) => {
        _this3.selectedSku[item.k_s] = _this3.initialSku[item.k_s] || _constants.UNSELECTED_SKU_VALUE_ID;
      }); // 只有一个 sku 规格值时默认选中

      this.skuTree.forEach((item) => {
        const key = item.k_s;
        const valueId = item.v[0].id;

        if (item.v.length === 1 && (0, _skuHelper.isSkuChoosable)(_this3.sku.list, _this3.selectedSku, {
          key,
          valueId,
        })) {
          _this3.selectedSku[key] = valueId;
        }
      });
      const skuValues = this.selectedSkuValues;

      if (skuValues.length > 0) {
        this.$nextTick(() => {
          _this3.$emit('sku-selected', {
            skuValue: skuValues[skuValues.length - 1],
            selectedSku: _this3.selectedSku,
            selectedSkuComb: _this3.selectedSkuComb,
          });
        });
      } // 重置商品属性


      this.selectedProp = {};
      const _this$initialSku$sele = this.initialSku.selectedProp;
      const selectedProp = _this$initialSku$sele === void 0 ? {} : _this$initialSku$sele; // 只有一个属性值时，默认选中，且选中外部传入信息

      this.propList.forEach((item) => {
        if (item.v && item.v.length === 1) {
          _this3.selectedProp[item.k_id] = [item.v[0].id];
        } else if (selectedProp[item.k_id]) {
          _this3.selectedProp[item.k_id] = selectedProp[item.k_id];
        }
      });
      const propValues = this.selectedPropValues;

      if (propValues.length > 0) {
        this.$emit('sku-prop-selected', {
          propValue: propValues[propValues.length - 1],
          selectedProp: this.selectedProp,
          selectedSkuComb: this.selectedSkuComb,
        });
      }
    },
    getSkuMessages: function getSkuMessages() {
      return this.$refs.skuMessages ? this.$refs.skuMessages.getMessages() : {};
    },
    getSkuCartMessages: function getSkuCartMessages() {
      return this.$refs.skuMessages ? this.$refs.skuMessages.getCartMessages() : {};
    },
    validateSkuMessages: function validateSkuMessages() {
      return this.$refs.skuMessages ? this.$refs.skuMessages.validateMessages() : '';
    },
    validateSku: function validateSku() {
      if (this.selectedNum === 0) {
        return t('unavailable');
      }

      if (this.isSkuCombSelected) {
        return this.validateSkuMessages();
      } // 自定义sku校验


      if (this.customSkuValidator) {
        const err = this.customSkuValidator(this);
        if (err) return err;
      }

      return t('selectSku');
    },
    onSelect: function onSelect(skuValue) {
      let _extends2; let
        _extends3;

      // 点击已选中的sku时则取消选中
      this.selectedSku = this.selectedSku[skuValue.skuKeyStr] === skuValue.id ? (0, _extends5.default)({}, this.selectedSku, (_extends2 = {}, _extends2[skuValue.skuKeyStr] = _constants.UNSELECTED_SKU_VALUE_ID, _extends2)) : (0, _extends5.default)({}, this.selectedSku, (_extends3 = {}, _extends3[skuValue.skuKeyStr] = skuValue.id, _extends3));
      this.$emit('sku-selected', {
        skuValue,
        selectedSku: this.selectedSku,
        selectedSkuComb: this.selectedSkuComb,
      });
    },
    onPropSelect: function onPropSelect(propValue) {
      let _extends4;

      const arr = this.selectedProp[propValue.skuKeyStr] || [];
      const pos = arr.indexOf(propValue.id);

      if (pos > -1) {
        arr.splice(pos, 1);
      } else if (propValue.multiple) {
        arr.push(propValue.id);
      } else {
        arr.splice(0, 1, propValue.id);
      }

      this.selectedProp = (0, _extends5.default)({}, this.selectedProp, (_extends4 = {}, _extends4[propValue.skuKeyStr] = arr, _extends4));
      this.$emit('sku-prop-selected', {
        propValue,
        selectedProp: this.selectedProp,
        selectedSkuComb: this.selectedSkuComb,
      });
    },
    onNumChange: function onNumChange(num) {
      this.selectedNum = num;
    },
    onPreviewImage: function onPreviewImage(indexImage) {
      const _this4 = this;

      const { previewOnClickImage } = this;
      const index = this.imageList.findIndex((image) => image === indexImage);
      const params = {
        index,
        imageList: this.imageList,
        indexImage,
      };
      this.$emit('open-preview', params);

      if (!previewOnClickImage) {
        return;
      }

      (0, _imagePreview.default)({
        images: this.imageList,
        startPosition: index,
        closeOnPopstate: true,
        onClose: function onClose() {
          _this4.$emit('close-preview', params);
        },
      });
    },
    onOverLimit: function onOverLimit(data) {
      const { action } = data;
      const { limitType } = data;
      const { quota } = data;
      const { quotaUsed } = data;
      const { handleOverLimit } = this.customStepperConfig;

      if (handleOverLimit) {
        handleOverLimit(data);
        return;
      }

      if (action === 'minus') {
        if (this.startSaleNum > 1) {
          (0, _toast.default)(t('minusStartTip', this.startSaleNum));
        } else {
          (0, _toast.default)(t('minusTip'));
        }
      } else if (action === 'plus') {
        if (limitType === QUOTA_LIMIT) {
          if (quotaUsed > 0) {
            (0, _toast.default)(t('quotaUsedTip', quota, quotaUsed));
          } else {
            (0, _toast.default)(t('quotaTip', quota));
          }
        } else {
          (0, _toast.default)(t('soldout'));
        }
      }
    },
    onStepperState: function onStepperState(data) {
      if (data.valid) {
        this.stepperError = null;
      } else {
        this.stepperError = (0, _extends5.default)({}, data, {
          action: 'plus',
        });
      }
    },
    onAddCart: function onAddCart() {
      this.onBuyOrAddCart('add-cart');
    },
    onBuy: function onBuy() {
      this.onBuyOrAddCart('buy-clicked');
    },
    onBuyOrAddCart: function onBuyOrAddCart(type) {
      // 有信息表示该sku根本不符合购买条件
      if (this.stepperError) {
        return this.onOverLimit(this.stepperError);
      }

      const error = this.validateSku();

      if (error) {
        (0, _toast.default)(error);
      } else {
        this.$emit(type, this.getSkuData());
      }
    },
    // @exposed-api
    getSkuData: function getSkuData() {
      return {
        goodsId: this.goodsId,
        selectedNum: this.selectedNum,
        selectedSkuComb: this.selectedSkuComb,
        messages: this.getSkuMessages(),
        cartMessages: this.getSkuCartMessages(),
      };
    },
  },
  render: function render() {
    const _this5 = this;

    const h = arguments[0];

    if (this.isSkuEmpty) {
      return;
    }

    const { sku } = this;
    const { goods } = this;
    const { price } = this;
    const { originPrice } = this;
    const { skuEventBus } = this;
    const { selectedSku } = this;
    const { selectedProp } = this;
    const { selectedNum } = this;
    const { stepperTitle } = this;
    const { selectedSkuComb } = this;
    const slotsProps = {
      price,
      originPrice,
      selectedNum,
      skuEventBus,
      selectedSku,
      selectedSkuComb,
    };

    const slots = function slots(name) {
      return _this5.slots(name, slotsProps);
    };

    const Header = slots('sku-header') || h(_SkuHeader.default, {
      attrs: {
        sku,
        goods,
        skuEventBus,
        selectedSku,
      },
    }, [h('template', {
      slot: 'sku-header-image-extra',
    }, [slots('sku-header-image-extra')]), slots('sku-header-price') || h('div', {
      class: 'van-sku__goods-price',
    }, [h('span', {
      class: 'van-sku__price-symbol',
    }, ['\uFFE5']), h('span', {
      class: 'van-sku__price-num',
    }, [price]), this.priceTag && h('span', {
      class: 'van-sku__price-tag',
    }, [this.priceTag])]), slots('sku-header-origin-price') || originPrice && h(_SkuHeaderItem.default, [t('originPrice'), ' \uFFE5', originPrice]), !this.hideStock && h(_SkuHeaderItem.default, [h('span', {
      class: 'van-sku__stock',
    }, [this.stockText])]), this.hasSkuOrAttr && !this.hideSelectedText && h(_SkuHeaderItem.default, [this.selectedText]), slots('sku-header-extra')]);
    const Group = slots('sku-group') || this.hasSkuOrAttr && h('div', {
      class: this.skuGroupClass,
    }, [this.skuTree.map((skuTreeItem) => h(_SkuRow.default, {
      attrs: {
        skuRow: skuTreeItem,
      },
    }, [skuTreeItem.v.map((skuValue) => h(_SkuRowItem.default, {
      attrs: {
        skuList: sku.list,
        skuValue,
        selectedSku,
        skuEventBus,
        skuKeyStr: skuTreeItem.k_s,
      },
    }))])), this.propList.map((skuTreeItem) => h(_SkuRow.default, {
      attrs: {
        skuRow: skuTreeItem,
      },
    }, [skuTreeItem.v.map((skuValue) => h(_SkuRowPropItem.default, {
      attrs: {
        skuValue,
        skuKeyStr: `${skuTreeItem.k_id}`,
        selectedProp,
        skuEventBus,
        multiple: skuTreeItem.is_multiple,
      },
    }))]))]);
    const Stepper = slots('sku-stepper') || h(_SkuStepper.default, {
      ref: 'skuStepper',
      attrs: {
        stock: this.stock,
        quota: this.quota,
        quotaUsed: this.quotaUsed,
        startSaleNum: this.startSaleNum,
        skuEventBus,
        selectedNum,
        stepperTitle,
        skuStockNum: sku.stock_num,
        disableStepperInput: this.disableStepperInput,
        customStepperConfig: this.customStepperConfig,
        hideQuotaText: this.hideQuotaText,
      },
      on: {
        change: function change(event) {
          _this5.$emit('stepper-change', event);
        },
      },
    });
    const Messages = slots('sku-messages') || h(_SkuMessages.default, {
      ref: 'skuMessages',
      attrs: {
        goodsId: this.goodsId,
        messageConfig: this.messageConfig,
        messages: sku.messages,
      },
    });
    const Actions = slots('sku-actions') || h(_SkuActions.default, {
      attrs: {
        buyText: this.buyText,
        skuEventBus,
        addCartText: this.addCartText,
        showAddCartBtn: this.showAddCartBtn,
      },
    });
    return h(_popup.default, {
      attrs: {
        round: true,
        closeable: true,
        position: 'bottom',
        getContainer: this.getContainer,
        closeOnClickOverlay: this.closeOnClickOverlay,
        safeAreaInsetBottom: this.safeAreaInsetBottom,
      },
      class: 'van-sku-container',
      model: {
        value: _this5.show,
        callback: function callback($$v) {
          _this5.show = $$v;
        },
      },
    }, [Header, h('div', {
      class: 'van-sku-body',
      style: this.bodyStyle,
    }, [slots('sku-body-top'), Group, slots('extra-sku-group'), Stepper, Messages]), slots('sku-actions-top'), Actions]);
  },
});

exports.default = _default2;
